package com.jushu.storbox.actions;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.jushu.storbox.LoginActivity;
import com.jushu.storbox.ShareDriveApplication;
import com.jushu.storbox.constant.ClientConfig;
import com.jushu.storbox.constant.ErrorConstant;
import com.jushu.storbox.constant.MessageCode;
import com.jushu.storbox.manager.ActivityTaskManager;
import com.jushu.storbox.manager.DownloadTaskManager;
import com.jushu.storbox.manager.UploadTaskManager;
import com.jushu.storbox.service.UserControl;
import com.jushu.storbox.util.LogUtil;
import com.jushu.storbox.util.PublicTools;
import com.huawei.sharedrive.sdk.android.common.Constants;
import com.huawei.sharedrive.sdk.android.exception.ClientException;
import com.huawei.sharedrive.sdk.android.modelV2.response.UserResponseV2;
import com.huawei.sharedrive.sdk.android.service.CommonClient;
import com.huawei.sharedrive.sdk.android.util.StringUtil;

public class BaseAction {

	private final static String TAG = BaseAction.class.getName();

	protected boolean checkToken(Context context, Handler messageHandler) {
		LogUtil.i(TAG, "checkToken");
		if (PublicTools.isAuthiorzationGotoTimeout(context)) {
			try {
				LogUtil.i(TAG, "start loginIn[Actions]");
				return loginInV2(context, PublicTools.getLoginUserName(context), PublicTools.getLoginUserPassFail(context));
			} catch (ClientException e) {
				if(e.getStatusCode() != ErrorConstant.CLIENT_ERROR_LOGIN_INFO) {
					handleException(e, messageHandler);
				} else {
					PublicTools.restartApp(context);
				}
				return false;
			}
		} else {
			return true;
		}
	}

	public boolean loginInV2(Context context, String userName, String passWord) throws ClientException {
		SharedPreferences settings = context.getSharedPreferences(ClientConfig.settings, Context.MODE_APPEND);
		String oldServerAddress = CommonClient.getInstance().getServiceURL();
		String newServerAddress = settings.getString(ClientConfig.SERVER_ADDRESS, "");
		CommonClient.getInstance().setServiceURL(newServerAddress);
		try {
			UserResponseV2 response = UserControl.Login(context, userName, passWord);
			if (null != response) {
				LogUtil.i(TAG, "loginIn success");
				if (StringUtil.isBlank(Constants.UAM_ADDRESS) || StringUtil.isBlank(ShareDriveApplication.getInstance().getUamAddress())
						|| StringUtil.isBlank(oldServerAddress) || !oldServerAddress.equals(newServerAddress)) {
					setAddress(Constants.UAM);
				}
				if (StringUtil.isBlank(Constants.UFM_ADDRESS) || StringUtil.isBlank(ShareDriveApplication.getInstance().getUfmAddress())
						|| StringUtil.isBlank(oldServerAddress) || !oldServerAddress.equals(newServerAddress)) {
					setAddress(Constants.UFM);
				}
				return true;
			} else {
				CommonClient.getInstance().setServiceURL(oldServerAddress);
			}
		} catch (ClientException e) {
			if(e.getStatusCode() != ErrorConstant.CLIENT_ERROR_LOGIN_INFO) {
				CommonClient.getInstance().setServiceURL(oldServerAddress);
				throw e;
			} else {
				PublicTools.restartApp(context);
			}
		}
		return false;
	}

	private void setAddress(String type) throws ClientException {
		LogUtil.i(TAG, "set address:" + type);
		ShareDriveApplication.getInstance().getUserClientV2().getServerAddress(getAuthCode(), type);
	}

	protected String getAuthCode() {
		String authCode = ShareDriveApplication.getInstance().getAuthorization();
		if (StringUtil.isBlank(authCode)) {
			authCode = "";
		}
		return authCode;
	}

	protected String getOnwerId() {
		String ownerId = "";
		if (null != ShareDriveApplication.getInstance().getWnerID()) {
			ownerId = ShareDriveApplication.getInstance().getWnerID();
		}
		return ownerId;
	}

	protected void handleException(ClientException e, Handler handler) {
		LogUtil.e(TAG, e.getCode() + "_" + e.getStatusCode());
		Message message = handler.obtainMessage();
		message.what = e.getStatusCode();
		message.obj = e;
		handler.sendMessage(message);
	}

	protected final void executeRunTask(Runnable runTask) {
		new Thread(runTask).start();
	}

	protected abstract class RealTaskRunnable implements Runnable {
		Context context;
		Handler msgHandler;

		public RealTaskRunnable(Context context, Handler msgHandler) {
			this.context = context;
			this.msgHandler = msgHandler;
		}

		@Override
		public final void run() {
			if (!ShareDriveApplication.getInstance().getWifiController().getNetworkState()) {
				if (msgHandler != null) {
					onNetworkUnAvailable(context, msgHandler);
				} else {
					LogUtil.e(TAG, "network unavalible and handler is null!");
				}
			} else {
				if (!checkToken(context, msgHandler)) {
					return;
				}
				try {
					doTask(context, msgHandler);
				} catch (ClientException e) {
					if (msgHandler != null && !filterException(e, msgHandler)) {
						Message message = msgHandler.obtainMessage();
						Bundle data = new Bundle();
						onTaskException(e, data);
						message.what = e.getStatusCode();
						message.obj = e;
						message.setData(data);
						message.sendToTarget();
					} else {
						LogUtil.e(TAG, e.getCode() + "_" + e.getStatusCode());
					}
				}
			}
		}

		protected abstract void doTask(Context context, Handler msgHandler) throws ClientException;

		protected void onNetworkUnAvailable(Context context, Handler msgHandler) {
			Message message = new Message();
			message.what = MessageCode.NETWORK_EXCEPTION;
			msgHandler.sendMessage(message);
		}

		/**
		 * @param e
		 * @param data
		 * 
		 *            if you translate this exception, please put "handle" to
		 *            data
		 */
		protected void onTaskException(ClientException e, Bundle data) {
		}

		/**
		 * @param e
		 *            witch exception happened
		 * @param handler
		 *            what to notify user interface(UI)
		 * @return true if handle this exception yourself, others false
		 */
		protected boolean filterException(ClientException e, Handler handler) {
			return false;
		}
	}

	public void logout(Activity activity) {
		// cancel download task
		DownloadTaskManager.cancelAllTask();

		// cancel upload task
		UploadTaskManager.cancelAllTask();

		SharedPreferences settings = activity.getSharedPreferences(ClientConfig.settings, Context.MODE_APPEND);
		Editor editor = settings.edit();
		editor.putBoolean(ClientConfig.AUTOLOGIN, false);
		PublicTools.setExpiredAt(activity, 0l);
		editor.putString(ClientConfig.USERNAME, "");
		PublicTools.setAuthorization(activity, "");
		PublicTools.setOwnerId(activity, "");
		editor.putString(ClientConfig.LOGINPASSWORD, "");
		editor.putBoolean(ClientConfig.NOT_NEED_NOTIFY, false);//
		PublicTools.setClientUserPassFail(activity, "");
		ShareDriveApplication.getInstance().setAuthorization(null);
		ShareDriveApplication.getInstance().setWnerID(null);
		editor.putString(ClientConfig.UAM_ADDRESS, "");
		editor.putString(ClientConfig.UFM_ADDRESS, "");
		editor.putBoolean(ClientConfig.LOGIN_STATE, false);
		editor.commit();
		Constants.UAM_ADDRESS = "";
		Constants.UFM_ADDRESS = "";

		Intent mHomeIntent = new Intent(Intent.ACTION_MAIN);  
		mHomeIntent.addCategory(Intent.CATEGORY_HOME);  
		mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
		                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);  
		try {
			ActivityTaskManager.getInstance().closeAllActivity();
			activity.finish();
		} finally {
			activity.startActivity(mHomeIntent);
		}
	}
}
